package cn.lg.soar.flow.api.utils;

import cn.lg.soar.flow.api.model.node.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public interface ProcessUtils {

    Long SYSTEM_USER_ID = 0L;

    String SYSTEM_APPROVAL = SYSTEM_USER_ID.toString();

    static List<ApprovalNode> getApprovalNodes(List<Node> nodes) {
        List<ApprovalNode> approvalNodes = new ArrayList<>();
        getApprovalNodes(approvalNodes, nodes);
        return approvalNodes;
    }

    static void getApprovalNodes(List<ApprovalNode> approvalNodes, List<Node> nodes) {
        for (Node node : nodes) {
            if (node instanceof ApprovalNode approvalNode) {
                approvalNodes.add(approvalNode);
            } else if (node instanceof ExclusiveGateway gateway) {
                List<ExclusiveGatewayItem> items = gateway.getItems();
                for (ExclusiveGatewayItem item : items) {
                    getApprovalNodes(approvalNodes, item.getNodes());
                }
            }
        }
    }

    static List<UserNode> getUserNodes(List<Node> nodes) {
        List<UserNode> userNodes = new ArrayList<>();
        getUserNodes(userNodes, nodes);
        return userNodes;
    }

    static void getUserNodes(List<UserNode> userNodes, List<Node> nodes) {
        for (Node node : nodes) {
            if (node instanceof UserNode userNode) {
                userNodes.add(userNode);
            } else if (node instanceof ExclusiveGateway gateway) {
                List<ExclusiveGatewayItem> items = gateway.getItems();
                for (ExclusiveGatewayItem item : items) {
                    getUserNodes(userNodes, item.getNodes());
                }
            }
        }
    }

    static void forEach(List<Node> nodes, Consumer<Node> consumer) {
        for (Node node : nodes) {
            consumer.accept(node);
            if (node instanceof ExclusiveGateway gateway) {
                List<ExclusiveGatewayItem> items = gateway.getItems();
                for (ExclusiveGatewayItem item : items) {
                    forEach(item.getNodes(), consumer);
                }
            }
        }
    }


    Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{([^}]+)\\}");

    /**
     * 填充模板中的占位符，例如 "{发起人}的请假申请-{发起时间}"
     *
     * @param template 模板字符串，如 "{发起人}的请假申请-{发起时间}"
     * @param variables 变量映射，key 为占位符名称（如 "发起人"），value 为替换值
     * @return 填充后的字符串
     */
    static String fillTemplate(String template, Map<String, Object> variables) {
        if (template == null) {
            return null;
        }
        if (variables == null || variables.isEmpty()) {
            return template;
        }

        Matcher matcher = PLACEHOLDER_PATTERN.matcher(template);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            String key = matcher.group(1).trim();
            Object value = variables.get(key);

            String replacement;
            if (value == null) {
                // 可选策略：保留原占位符 / 替换为空 / 抛异常
                replacement = matcher.group(0);
                // replacement = ""; // 或替换为空
                // throw new IllegalArgumentException("模板变量未提供: " + key);
            } else {
                replacement = value.toString();
            }
            // 转义 $ 和 \，防止 replaceAll 报错（使用 appendReplacement 会自动处理）
            matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    static String toUserApproval(Long userId) {
        if  (userId == null) {
            return null;
        }
        return "" + userId;
    }

    static String toPostApproval(Long postId) {
        if  (postId == null) {
            return null;
        }
        return "P" + postId;
    }

    static Long toUserId(String approval) {
        if  (approval == null) {
            return null;
        }
        return Long.parseLong(approval);
    }

    static Long toPostId(String approval) {
        if  (approval == null) {
            return null;
        }
        return Long.parseLong(approval.substring(1));
    }

    static boolean isUser(String approval) {
        if  (approval == null) {
            return false;
        }
        if (approval.startsWith("P")) {
            return false;
        }
        return true;
    }

    static boolean isPost(String approval) {
        if  (approval == null) {
            return false;
        }
        return approval.startsWith("P");
    }

}
